<template>
	<div class="puzzle" :style="{width:width+'px',height:height+'px'}">
		<div v-for="(item,index) in blockPoints" :key="item.id" :style="{width:blockWidth+'px',
        height:blockHeight+'px',
        left:item.x+'px',top:item.y+'px',
        backgroundImage:`url(${imgSrc})`,
        backgroundPosition:`-${correctPoints[index].x}px -${correctPoints[index].y}px`,
        opacity: index===blockPoints.length-1 && 0 }" v-on:click="handleClick" class="puzzle__block"
			:ref="index===blockPoints.length-1?'empty':'block'" :data-correctX="correctPoints[index].x"
			:data-correctY="correctPoints[index].y"></div>
	</div>
</template>
<script>
	export default {
		props: {
			imgSrc: {
				type: String,
				required: true
			},
			width: {
				// 图片总宽度
				type: Number,
				default: 300,
			},
			height: {
				// 图片总高度
				type: Number,
				default: 300,
			},
			row: {
				// 行数
				type: Number,
				default: 3,
			},
			col: {
				// 列数
				type: Number,
				default: 3,
			},
		},
		data() {
			return {
				status: {
					type: String,
					default: "进行中......",
				},
			};
		},
		methods: {
			handleClick(e) {
				const blockDom = e.target;
				const empthDom = this.$refs.empty[0];
				const {
					left,
					top
				} = blockDom.style;
				if (!this.isAdjacent(blockDom, empthDom)) {
					return;
				}
				//交换元素
				blockDom.style.left = empthDom.style.left;
				blockDom.style.top = empthDom.style.top;
				empthDom.style.left = left;
				empthDom.style.top = top;
				const winFlag = this.winCheck();
				if (winFlag) {
					//   console.log('success');
					this.winGame(empthDom);
				}
			},
			isAdjacent(blockDom, empthDom) {
				// 判断是否相邻
				const {
					left: blockLeft,
					top: blockTop,
					width,
					height
				} = blockDom.style;
				const {
					left: emptyLeft,
					top: emptyTop
				} = empthDom.style;
				const xDis = Math.floor(
					Math.abs(parseFloat(blockLeft) - parseFloat(emptyLeft))
				);
				const yDis = Math.floor(
					Math.abs(parseFloat(blockTop) - parseFloat(emptyTop))
				);
				const flag =
					(blockLeft === emptyLeft && yDis === parseInt(height)) ||
					(blockTop === emptyTop && xDis === parseInt(width));
				console.log(flag);
				return flag;
			},
			winCheck() {
				// 判断是否完成
				const blockDomArr = this.$refs.block;
				return blockDomArr.every((dom) => {
					const {
						left: domLeft,
						top: domTop
					} = dom.style;
					const {
						correctx: correctX,
						correcty: correctY
					} = dom.dataset;
					const flag =
						parseInt(domLeft) === parseInt(correctX) &&
						parseInt(domTop) === parseInt(correctY);
					return flag;
				});
				// console.log(blockDomArr.length);
			},
			winGame(empthDom) {
				//通关
				setTimeout(() => {
					this.status = "胜利";
					alert("恭喜通关");
					empthDom.style.opacity = 1;
					this.$emit("getStatus");
					setTimeout(() => {
						this.goToNextLevel();
					}, 300);
				}, 300);
			},
			goToNextLevel() {
				const answerFlag = window.confirm("现在进行下一关么？");
				if (answerFlag) {
					this.status = "进行中......";
					this.$emit("next");
				}
			},
		},
		computed: {
			blockWidth() {
				return this.width / this.col;
			},
			blockHeight() {
				return this.height / this.row;
			},
			correctPoints() {
				const {
					row,
					col,
					blockWidth,
					blockHeight
				} = this;
				const arr = [];
				for (let i = 0; i < row; i++) {
					for (let j = 0; j < col; j++) {
						arr.push({
							x: j * blockWidth,
							y: i * blockHeight,
							id: new Date().getTime() + Math.random() * 100,
						});
					}
				}
				return arr;
			},
			blockPoints() {
				const points = this.correctPoints;
				const length = points.length; //数组的长度
				const lastEle = points[length - 1]; //最后一个元素
				const newArr = [...points];
				newArr.length = length - 1;
				//打乱顺序
				newArr.sort(() => Math.random() - 0.5);
				newArr.push(lastEle);
				return newArr;
			},
		},
	};
</script>
<style>
	.puzzle {
		box-sizing: content-box;
		border: 2px solid #cccccc;
		position: relative;
		margin: 10px auto;
	}

	.puzzle__block {
		border: 1px solid #ffffff;
		box-sizing: border-box;
		/* background-color: rebeccapurple; */
		position: absolute;
		transition: all 0.3s;
	}
</style>